import android.view.LayoutInflater
import android.view.ViewGroup
import android.widget.ImageView
import android.widget.TextView
import androidx.recyclerview.widget.DiffUtil
import androidx.recyclerview.widget.RecyclerView
import com.bumptech.glide.Glide
import com.fenghongzhang.club_2303.R
import com.fenghongzhang.club_2303.test.rv.ItemBean

class MyAdapter : RecyclerView.Adapter<MyAdapter.MyViewHolder>() {

    private var dataList: List<ItemBean> = emptyList()

    // 更新数据并通过DiffUtil计算差异
    fun updateData(newList: List<ItemBean>) {
        val diffResult = DiffUtil.calculateDiff(ItemDiffCallback(dataList, newList))
        dataList = newList
        diffResult.dispatchUpdatesTo(this) // 分发差异到适配器
    }

    // 局部更新单一项的指定字段（对外调用）
    fun updateItemPartially(
        itemId: Int, // 通过id定位item（比position更可靠）
        newImgRes: String? = null,
        newText: String? = null
    ) {
        val newList = dataList.map { item ->
            if (item.id == itemId) {
                // 只修改传入的字段，其他字段保持不变
                item.copy(
                    imgRes = newImgRes ?: item.imgRes,
                    text = newText ?: item.text
                )
            } else {
                item
            }
        }
        updateData(newList)
    }


    inner class MyViewHolder(itemView: android.view.View) : RecyclerView.ViewHolder(itemView) {
        val ivImage: ImageView = itemView.findViewById(R.id.iv_image)
        val tvText: TextView = itemView.findViewById(R.id.tv_text)

        // 绑定数据，支持payload局部刷新
        fun bind(item: ItemBean, payloads: List<Any>) {
            if (payloads.isNotEmpty()) {
                // 有payload：只更新变化的字段
                val payload = payloads[0] as? MutableMap<String, Any> ?: return
                // 图片变化时才刷新ImageView
                if (payload.containsKey("imgRes")) {
                    Glide.with(itemView.context).load(item.imgRes).into(ivImage)
                }
                // 文字变化时才刷新TextView
                if (payload.containsKey("text")) {
                    tvText.text = payload["text"] as String
                }
            } else {
                // 无payload：全量刷新（首次绑定或所有字段都变）
                Glide.with(itemView.context).load(item.imgRes).into(ivImage)
                tvText.text = item.text
            }
        }
    }

    override fun onCreateViewHolder(parent: ViewGroup, viewType: Int): MyViewHolder {
        val view = LayoutInflater.from(parent.context)
            .inflate(R.layout.item_layout, parent, false)
        return MyViewHolder(view)
    }

    // 优先处理带payload的绑定
    override fun onBindViewHolder(holder: MyViewHolder, position: Int, payloads: MutableList<Any>) {
        holder.bind(dataList[position], payloads)
    }

    // 兼容无payload的情况
    override fun onBindViewHolder(holder: MyViewHolder, position: Int) {
        holder.bind(dataList[position], emptyList())
    }

    override fun getItemCount() = dataList.size

    // DiffUtil回调：计算差异并生成payload
    private class ItemDiffCallback(
        private val oldList: List<ItemBean>,
        private val newList: List<ItemBean>
    ) : DiffUtil.Callback() {

        override fun getOldListSize() = oldList.size
        override fun getNewListSize() = newList.size

        // 判断是否为同一个item（通过唯一id）
        override fun areItemsTheSame(oldPos: Int, newPos: Int): Boolean {
            return oldList[oldPos].id == newList[newPos].id
        }

        // 判断内容是否完全相同
        override fun areContentsTheSame(oldPos: Int, newPos: Int): Boolean {
            val old = oldList[oldPos]
            val new = newList[newPos]
            return old.imgRes == new.imgRes && old.text == new.text
        }

        // 内容不同时，返回变化的字段（生成payload）
        override fun getChangePayload(oldPos: Int, newPos: Int): Any? {
            val old = oldList[oldPos]
            val new = newList[newPos]
            val payload = mutableMapOf<String, Any>()

            // 只记录变化的字段
            if (old.imgRes != new.imgRes) {
                payload["imgRes"] = new.imgRes
            }
            if (old.text != new.text) {
                payload["text"] = new.text
            }

            return if (payload.isNotEmpty()) payload else null
        }
    }
}